package com.zdp.chat.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.anwen.mongo.conditions.query.LambdaQueryChainWrapper;
import com.anwen.mongo.model.PageParam;
import com.anwen.mongo.model.PageResult;
import com.google.common.collect.Maps;
import com.zdp.chat.common.CommonConstant;
import com.zdp.chat.entity.chat.ChatMessageReq;
import com.zdp.chat.entity.mongo.RoomMessageDoc;
import com.zdp.chat.enums.MessageStatusEnum;
import com.zdp.chat.service.WebSocketService;
import com.zdp.chat.service.mongo.RoomMessageDocService;
import com.zdp.chat.util.CacheUtils;
import lombok.RequiredArgsConstructor;
import org.redisson.client.protocol.ScoredEntry;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@RequiredArgsConstructor
@RestController
@RequestMapping("/chat")
public class ChatController {

    private final WebSocketService webSocketService;

    private final RedisTemplate redisTemplate;

    private final RoomMessageDocService roomMessageDocService;

    @PostMapping("/send")
    public <T> Object send(@RequestBody ChatMessageReq<T> req) {
        webSocketService.send(req);
        return "send msg success!~";
    }

    @PostMapping("/room/list")
    public Object roomList(@RequestBody JSONObject param) {
        String uid = param.getString("uid");
        // 当前所在的房间id
        String roomId = param.getString("roomId");
        Integer pageNum = param.getInteger("pageNum");
        Integer pageSize = param.getInteger("pageSize");
        int end = pageNum * pageSize;
        int start = Math.max(0, (pageNum - 1) * pageSize);

        Collection<ScoredEntry<String>> cacheList = CacheUtils.zGet(String.format(CommonConstant.USER_ROOM_KEY, uid), start, end);
        if (CollUtil.isEmpty(cacheList)) {
            return null;
        }

        // 删除房间将房间时间改为0 用户-房间缓存
        List<Long> roomIds = cacheList.stream().filter(x -> x.getScore() > 0).map(x -> Long.parseLong(String.valueOf(x.getValue()))).toList();
        if (CollUtil.isEmpty(roomIds)) {
            return null;
        }
        // 获取房间最后一条消息
        List<String> roomLastMsgList = roomIds.stream().map(x -> String.valueOf(redisTemplate.opsForValue().get(String.format(CommonConstant.ROOM_INFO_KEY, x)))).toList();
        Map<Long, String> roomLastMsgMap = IntStream.range(0, Math.min(roomIds.size(), roomLastMsgList.size()))
                .boxed()
                .collect(Collectors.toMap(i -> roomIds.get(i), i -> roomLastMsgList.get(i)));


        // 计算未读消息个数 [用户在该房间最新的活跃度,房间当前的活跃度]
        List<Long> roomUnReadCountList = roomIds.stream().map(x -> {
            LocalDateTime roomActiveTime = DateUtil.toLocalDateTime(DateUtil.date((CacheUtils.getScore(String.format(CommonConstant.USER_ROOM_KEY, uid), x)).longValue()));
            LocalDateTime userActiveTime = DateUtil.toLocalDateTime(DateUtil.date((CacheUtils.getScore(String.format(CommonConstant.ROOM_USER_KEY, x), uid)).longValue()));
            LambdaQueryChainWrapper<RoomMessageDoc> chainWrapper = new LambdaQueryChainWrapper<>(null, RoomMessageDoc.class)
                    .eq(RoomMessageDoc::getMsgStatus, MessageStatusEnum.NORMAL.getStatus())
                    .between(RoomMessageDoc::getSendTime, userActiveTime, roomActiveTime, false);
            return roomMessageDocService.count(chainWrapper);
        }).toList();
        Map<Long, Long> roomUnReadCountMap = IntStream.range(0, Math.min(roomIds.size(), roomLastMsgList.size()))
                .boxed()
                .collect(Collectors.toMap(i -> roomIds.get(i), i -> roomUnReadCountList.get(i)));

        // 获取当前房间的前20条消息
        LambdaQueryChainWrapper<RoomMessageDoc> chainWrapper = new LambdaQueryChainWrapper<>(null, RoomMessageDoc.class)
                .orderByDesc(RoomMessageDoc::getSendTime)
                .eq(RoomMessageDoc::getRoomId, Long.parseLong(roomId))
                .eq(RoomMessageDoc::getMsgStatus, MessageStatusEnum.NORMAL.getStatus());

        PageResult<RoomMessageDoc> page = roomMessageDocService.page(chainWrapper, new PageParam(1, 10));

        List<Map<String, Object>> collect = roomIds.stream().map(x -> {
            Map<String, Object> result = Maps.newHashMap();
            result.put("roomId", x);
            result.put("unReadNum", roomUnReadCountMap.get(x));
            result.put("lastMsg", roomLastMsgMap.get(x));
            result.put("pageResult", null);
            if (roomId.equals(String.valueOf(x))) {
                result.put("pageResult", page);
            }
            return result;
        }).toList();


        return collect;
    }

    @PostMapping("/join/room")
    public Object joinRoom(@RequestBody JSONObject param) {
        String uid = param.getString("uid");
        Long roomId = param.getLong("roomId");
        Long oldRoomId = param.getLong("oldRoomId");





        return null;
    }

    @PostMapping("/room/delete")
    public Object roomDelete() {
        return null;
    }


}
